﻿using System;
using System.Windows.Input;
using System.Windows.Interactivity;
using System.Windows.Media.TextFormatting;
using AesonBaseFramework.EntityFramework.DbContexts;
using AesonBaseFramework.EntityFramework.Helpers;
using AesonIdentityLibrary.DataContext;
using AesonIntegrationTestLibrary.DataModel;
using AesonIntegrationTestLibrary.PubSubEvents;
using AesonIntegrationTestLibrary.Tools;
using AesonIntegrationTestModul.Config;
using Microsoft.Practices.Prism.Commands;
using Microsoft.Practices.Prism.Interactivity.InteractionRequest;
using Microsoft.Practices.Prism.Logging;
using Microsoft.Practices.Prism.Mvvm;
using Microsoft.Practices.Prism.PubSubEvents;
using Microsoft.Practices.Unity;
using System.Collections.ObjectModel;
using System.Windows.Data;

namespace AesonIntegrationTestModul.Views
{

 
    public class IntegrationTestViewViewModel : BindableBase
    {
        #region Field from Ctor
        public IUnityContainer Container { get; set; }
        public ILoggerFacade Logger { get; set; }
        public IEventAggregator EventAggregator { get; set; }
        #endregion

        #region Command
        public DelegateCommand InitializeDatabaseCommand { get; set; }
        public DelegateCommand ShowDetailCommand { get; set; }
        #endregion

        #region Field
        public ObservableCollection<AesonTest> Tests { get; set; }
        private static readonly object _lock = new object();

        public AesonTest SelectedTest { get; set; }

        public InteractionRequest<INotification> ShowDetailRequest { get;  set; }


        private string statut;
        public string Statut
        {
            get { return statut; }
            set { SetProperty(ref this.statut, value); }
        }

        #endregion




        #region Ctor
        public IntegrationTestViewViewModel(IUnityContainer container, IEventAggregator eventAgregator)
        {
            #region Field assignation
            this.Container = container;
            this.EventAggregator = eventAgregator;
            Tests = new ObservableCollection<AesonTest>();
            BindingOperations.EnableCollectionSynchronization(Tests, _lock);
            #endregion

            #region CommandAssignation
            this.InitializeDatabaseCommand = new DelegateCommand(InitializeDatabase);
            this.ShowDetailCommand = new DelegateCommand(SHowDetail);
            this.ShowDetailRequest = new InteractionRequest<INotification>();
            #endregion

            #region EventSubscribtion
            EventAggregator.GetEvent<TestResultEvent>().Subscribe(ShowTestResult);
            #endregion

        }

        private void SHowDetail()
        {
            this.ShowDetailRequest.Raise(new Notification()
            {
                Content = SelectedTest, Title = "Test details"
            });
        }
        #endregion

        #region Methode
        private void ShowTestResult(AesonTest result)
        {
            Tests.Insert(0, result);
        }

        
        #endregion

        private async void InitializeDatabase()
        {
            #region Builder
            SecurityDbContext ctx = SecurityDbContext.Create(DbConnectionInfo.Create(TestConfig.IntegrationUser,
              TestConfig.DatabaseServer, TestConfig.TargetDatabaseName));

            var dm = DatabaseinItializerModel.Create(
                ctx, TestConfig.BacPacPackagePath,
                ConnectionStringFactory.GetConnectionString(TestConfig.DatabaseServer, TestConfig.TargetDatabaseName),
                TestConfig.TargetDatabaseName);
            #endregion

            EventAggregator.GetEvent<AesonTestFlowStartedEvent>().Subscribe(TestFlowStarted);
            EventAggregator.GetEvent<AesonTestCreatedEvent>().Subscribe(AesonTestCreated);

            var tf = AesonTestFlow.Create(EventAggregator, 1);
            tf.AddTest(await DatabaseInitializer.InitializeDatabase(dm, EventAggregator));
            tf.AddTest(await DatabaseInitializer.InitializeDatabase(dm, EventAggregator));
            tf.AddTest(await DatabaseInitializer.InitializeDatabase(dm, EventAggregator));


            var result = tf.EndTest();


        }



        private void TestFlowStarted(AesonTestFlow tf)
        {
            Statut = "Aeson test number " + tf.TestNumber + " Started at " + tf.StartDate;
        }

        private void AesonTestCreated(AesonTest t)
        {
            Tests.Add(t);
        }

    
        




    }

  
}
